package com.liusr.template.exception;

import com.liusr.template.common.result.Result;
import com.liusr.template.common.result.ResultData;
import com.liusr.template.common.result.ResultEnum;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpStatus;
import org.springframework.http.converter.HttpMessageNotReadableException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.util.NestedServletException;

/**
 * @author Liusr
 * @date 2023/1/23
 * @package com.liusr.template.exception
 * @Description: 自定义全局异常处理器
 */
@Slf4j
@RestControllerAdvice
public class CustomGlobalExceptionHandler {
	/**
	 * 自定义业务异常
	 *
	 * @param e e
	 * @return Result<String>
	 */
	@ExceptionHandler(CustomBusinessException.class)
	@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
	public Result<String> customException(CustomBusinessException e) {
		log.error("自定义异常信息：{}", e.getMessage());
		return ResultData.customResp(ResultEnum.SERVER_ERROR.getCode(), ResultEnum.SERVER_ERROR.getMsg(), e.getMessage());
	}

	/**
	 * Http请求消息序列化异常
	 *
	 * @param e e
	 * @return Result<String>
	 */
	@ExceptionHandler({HttpMessageNotReadableException.class})
	@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
	public Result<String> httpNotReadableException(HttpMessageNotReadableException e) {
		log.error("Http请求消息序列化异常：{}", e.getMessage());
		log.error("HttpMessageNotReadableException：传入类型错误或没有传参错误！");
		return ResultData.customResp(ResultEnum.SERVER_ERROR.getCode(), "Http请求消息序列化异常", e.getMessage());
	}

	/**
	 * 用户未登录异常
	 *
	 * @param e e
	 * @return Result<String>
	 */
	@ExceptionHandler({NoLoginException.class})
	@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
	public Result<String> noLoginException(NoLoginException e) {
		log.error("用户未登录异常：{}", e.getMessage());
		return ResultData.customResp(ResultEnum.SERVER_ERROR.getCode(), "用户未登录！");
	}

	/**
	 * Token验证错误异常
	 *
	 * @param e e
	 * @return Result<String>
	 */
	@ExceptionHandler({TokenErrorException.class})
	@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
	public Result<String> tokenErrorException(TokenErrorException e) {
		log.error("Token验证错误异常：{}", e.getMessage());
		return ResultData.customResp(ResultEnum.SERVER_ERROR.getCode(), "Token验证错误！");
	}

	/**
	 * 参数错误异常
	 *
	 * @param e e
	 * @return Result<String>
	 */
	@ExceptionHandler({ParamErrorException.class})
	@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
	public Result<String> paramErrorException(ParamErrorException e) {
		log.error("参数错误异常：{}", e.getMessage());
		return ResultData.customResp(ResultEnum.SERVER_ERROR.getCode(), e.getMessage());
	}

	/**
	 * 堆栈溢出错误
	 *
	 * @param e e
	 * @return Result<String>
	 */
	@ExceptionHandler({NestedServletException.class, StackOverflowError.class})
	@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
	public Result<String> stackOverflowException(Exception e) {
		log.error("堆栈溢出错误：{}", e.getMessage());
		return ResultData.serverError("堆栈溢出错误！");
	}

	/**
	 * 全局异常
	 *
	 * @param e e
	 * @return Result<String>
	 */
	@ExceptionHandler({Exception.class})
	@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
	public Result<String> overallException(Exception e) {
		log.error("全局异常信息：{}", e.getMessage());
		System.out.println(e.getClass());
		return ResultData.unKnowError("全局异常！");
	}
}
